GEMC simulation results for custom Helium potential

More
5 years 7 months ago #515 by emarin
Hello! We are looking into this and will respond ASAP.

Quick check: Your energy units in step #3 seem to be in K, but Cassandra uses amu A^2/ps^2 internally (see for instance, the conversion from K to amu A^2/ps^2 in line 1501 in input_routines.f90 for the epsilon of the standard LJ potential).
The following user(s) said Thank You: ramess101

Please Log in to join the conversation.

  • ramess101
  • ramess101's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 7 months ago #516 by ramess101
Eliseo,

Thank you for responding to me question. I need to apologize though, I thought that Ed had removed this question after I emailed on August 22nd saying that I found this energy units issue. Indeed, by converting to amu A^2/ps^2 we get the correct GEMC results. I hope that you did not spend too much time trying to debug our code.

Thanks again
The following user(s) said Thank You: emarin

Please Log in to join the conversation.

More
5 years 7 months ago #517 by ejmaginn
Rich that was my fault. I "approved" your message and so it went out to everyone. Also, Ryan Mullen is looking into the other error you identified and hopefully that should be cleaned up soon.
The following user(s) said Thank You: ramess101

Please Log in to join the conversation.

  • ramess101
  • ramess101's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 7 months ago #521 by ramess101
Eliseo and/or Ed,

Now that we have the two-body Helium potential working, our next (and final) task is to implement a three-body Helium potential.

We already have the Fortran 90 code written that takes as input three interatomic distances (rij, rik, and rjk) and outputs the three-body energy. It was readily obvious for the two-body Helium potential that we just needed to call our two-body function in the Compute_AtomPair_Energy subroutine. However, since Cassandra does not have a "Compute_ThreeBody_Energy" subroutine, it is not as clear to me what the best approach is moving forward. Since you are much more familiar with the Cassandra code and have likely given some thought to the implementation of three-body potentials, I was hoping you could provide some insight.

Here is my (naive) idea so far:

1) After calling Compute_MolecularPair_Energy within Compute_Molecule_Nonbond_Inter_Energy (around line 884 in energy_routines), include an additional loop over all the molecules/atoms that are not "is" or "ispecies" (call this "ithird")
2) Call Check_MolecularPair_Cutoff for the distances between ithird and is/ispecies.
3) If these additional two distances are also within the cut-off, call Compute_ThreeBody_Energy and add this to the Eij_inter_vdw term (we could try separating this into its own variable if we want to)

Note that I'm not sure right now how we would avoid double counting the interactions with this approach.

One benefit of this approach is that we only have to loop through the third molecule/atom and we only do this after we have determined that the first two are within the cut-off. Another (more intuitive) option would be to call Compute_ThreeBody_Energy within the move_* files (e.g., move_delete) after calling the other Compute_* subroutines (e.g., Compute_Molecular_Bond_Energy). From what I can tell, the downside to this approach is that we would be repeating the time consuming calculation of looping through N molecules, which is already being performed within Compute_Molecule_Nonbond_Inter_Energy.

In brief, do you think this approach would work? If you have concerns, what would be the simplest, fastest, or best way to implement a three-body potential in Cassandra?

Thank you

Please Log in to join the conversation.

More
5 years 7 months ago - 5 years 7 months ago #522 by emarin
Hello!

We think there are two solutions to this:

1) Use a neighbor list: probably the cleanest to solve this. If a neighbor list is available, then for any two molecules A and B, the triads can be found by taking the intersection of the A and B neighbors. If you decide to go this route, I have code that hasn't been distributed that I can share (although you might need to test it a bit :-) )

2) Do something analogous to pair_nrg_array. The variable pair_nrg_array is an NxN matrix that stores the interaction energy between a pair of molecules. This matrix is always available in memory. We use it to retrieve the initial interaction energy before each MC move, so we save one energy computation each MC move. If a move is accepted, we update the corresponding 2 elements in pair_nrg_array. If it is rejected, we do not update it.

You could implement something like triad_nrg_array(i,j,k). This solution would involve adding two loops after the Check_MoleculePair_Cutoff in Compute_Molecule_Nonbond_inter_Energy: The first loop will go from imolecule +1 to nmols(ispecies,this_box) and another loop to go from ispecies +1, nspecies and over all the molecules for these species.

Let us know what you think!
Last Edit: 5 years 7 months ago by emarin.

Please Log in to join the conversation.

  • ramess101
  • ramess101's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 7 months ago #523 by ramess101
Eliseo,

Thank you for the response. Here are my thoughts regarding the two methods:

1) Yes, a neighbor list is definitely a good way to go. If you already have some code that would be useful for this, then I would certainly like to take a look at it. What would be the best way for you to share that with me? I guess I assumed that Cassandra already implemented a neighbor list, but is that not the case? From what I remember, neighbor lists are less common in Monte Carlo codes than Molecular Dynamics because of regrowth, insertion, and deletion moves. Is that why Cassandra does not use a neighbor list and instead stores the pair_nrg_array?

2) So essentially triad_nrg_array would be an NxNxN matrix? Do you have any concerns with regards to memory and speed if N >> 1000? As far as the implementation, are there any simplifications that we can make considering we only have one molecule type and that molecule consists of only a single atom (Helium)? Also, do we need to add two loops or just one? I thought we already have a double loop which goes over all pairs of interactions, so it seems like we would only need one additional loop. But perhaps I am misunderstanding your explanation. To address my confusion, can you briefly define what ispecies and nspecies represent? For example, a simulation with united-atom representations of 100 propane molecules and 50 butane molecules. Is nspecies 2, 100, 50, 150, (3*100), (4*50), or (3*100 + 4*50)? Or for the specific problem at hand, with a simulation of 1000 Helium atoms is nspecies 1 or 1000?

Thanks again

Rich
The following user(s) said Thank You: ejmaginn

Please Log in to join the conversation.

Time to create page: 0.134 seconds